#ifndef HTTP_H
#define HTTP_H

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

static int sendf(int socket_fd, const char *format, ...) {
    char str[1024];
    va_list vlist;
    va_start(vlist, format);
    vsprintf(str, format, vlist);
    va_end(vlist);

    int n = strlen(str);
    if (str[n - 1] != '\r') {
        str[n++] = '\r';
        str[n] = 0;

        if (str[n - 1] != '\n') {
            str[n++] = '\n';
            str[n] = 0;
        }
    }
    return ::send(socket_fd, str, n, 0);
}

static size_t sock_recvln(int __fd, void *__buf, size_t __n) {
    char *p = (char *)__buf;
    size_t ret = 0;
    while (__n > 0) {
        if (recv(__fd, p, 1, 0) == 1) {
            if (*p == '\n') {
                if (p == __buf) continue;
                p[1] = 0;
                ret++;
                return ret;
            }
            p++;
            ret++;
            __n--;
        } else {
            return -1;
        }
    }

    *(p - 1) = 0;
    return ret;
}

static void send_404(int socket_fd) {
    sendf(socket_fd, "HTTP/1.1 404 Not Found");
    sendf(socket_fd, "Content-Type: text/html; charset=utf-8");
    sendf(socket_fd, "Content-Length: 0");
    sendf(socket_fd, "Connection: close");
    sendf(socket_fd, "");
}

static void send_200(int socket_fd, size_t size, std::string ContentType, bool keep_alive) {
    sendf(socket_fd, "HTTP/1.1 200 OK");
    sendf(socket_fd, "Content-Type: text/html; charset=utf-8");
    sendf(socket_fd, "Content-Length: %zu", size);
    if (ContentType.size() > 0) {
        sendf(socket_fd, "Content-Type: %s", ContentType.c_str());
    }
    if (keep_alive) {
        sendf(socket_fd, "Connection: keep-alive");
    } else {
        sendf(socket_fd, "Connection: close");
    }
    sendf(socket_fd, "");
}

#endif
